package com.yanjr.modules.sys.service.impl;

import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.yanjr.common.Constants;
import com.yanjr.common.persistence.Page;
import com.yanjr.common.utils.IdGen;
import com.yanjr.common.utils.StringUtils;
import com.yanjr.modules.sys.dao.MenuDao;
import com.yanjr.modules.sys.dao.OfficeDao;
import com.yanjr.modules.sys.dao.RoleDao;
import com.yanjr.modules.sys.dao.UserDao;
import com.yanjr.modules.sys.entity.Menu;
import com.yanjr.modules.sys.entity.Role;
import com.yanjr.modules.sys.entity.User;
import com.yanjr.modules.sys.security.SystemAuthorizingRealm;
import com.yanjr.modules.sys.service.SystemService;
import com.yanjr.modules.sys.utils.UserUtils;

@Service("systemService")
@Transactional(readOnly = true)
public class SystemServiceImpl implements SystemService {

	@Autowired
	private UserDao userDao;
	@Autowired
	private MenuDao menuDao;
	@Autowired
	private RoleDao roleDao;
	@Autowired
	private OfficeDao officeDao;
	@Autowired
	private SystemAuthorizingRealm systemRealm;
	
	
	@Override
	public User getUser(String id) {
		return userDao.getUser(id);
	}

	@Override
	public Page<User> findUser(Page<User> page, User user) {
		StringBuffer sql = new StringBuffer("select o1.name company_name, o2.name office_name, u.* "
				+ "from sys_user u left join sys_office o1 on (u.company_id=o1.id and o1.type='1' and o1.del_flag='0') "
				+ "left join sys_office o2 on (u.office_id=o2.id and o2.type='2') where u.del_flag='0' ");
		if(StringUtils.isNotEmpty(user.getCompanyId())) {
			sql.append(" and company_id='" + user.getCompanyId() + "'");
		}
		if(StringUtils.isNotEmpty(user.getOfficeId())) {
			sql.append(" and office_id='" + user.getOfficeId() + "'");
		}
		if(StringUtils.isNotEmpty(user.getLoginName())) {
			sql.append(" and login_name like '%" + user.getLoginName() + "%'");
		}
		if(StringUtils.isNotEmpty(user.getName())) {
			sql.append(" and name='" + user.getName() + "'");
		}
		
		return userDao.findPage(page, sql.toString());
	}

	@Override
	public String getDataScope(User user) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public User getUserByLoginName(String loginName) {
		User user = userDao.findByLoginName(loginName);
		if(user != null) {
			List<Role> list = roleDao.findByUserId(user.getId());
			if(list != null && list.size() > 0) {
				user.setRoleList(list);
			}
		}
		return user;
	}

	@Override
	@Transactional(readOnly = false)
	public void saveUser(User user) {
		if(StringUtils.isEmpty(user.getId())) {
			userDao.save(user);
		} else {
			userDao.update(user);
		}
		//clear cache
		systemRealm.clearAllCachedAuthorizationInfo();
	}

	@Override
	@Transactional(readOnly = false)
	public void deleteUser(String id) {
		userDao.deleteById(id);
	}

	@Override
	@Transactional(readOnly = false)
	public void updatePasswordById(String id, String loginName,
			String newPassword) {
		userDao.updatePasswordById(UserUtils.entryptPassword(newPassword), id);
		//clear cache
		systemRealm.clearCachedAuthorizationInfo(loginName);
	}

	@Override
	public void updateUserLoginInfo(String id) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public Role getRole(String id) {
		Role role = roleDao.get(id);
		if(role != null) {
			role.setOffice(officeDao.get(role.getOfficeId()));
			role.setMenuList(menuDao.findByRoleId(id));
			role.setUserList(userDao.findByRoleId(id));
			role.setOfficeList(officeDao.findByRoleId(id));
		}
		return role;
	}

	@Override
	public Role findRoleByName(String name) {
		return roleDao.findByName(name);
	}

	@Override
	public List<Role> findAllRole() {
		List<Role> list = roleDao.findAllList();
		for(Role r : list) {
			r.setOffice(officeDao.get(r.getOfficeId()));;
		}
		return list;
	}

	@Override
	@Transactional(readOnly = false)
	public void saveRole(Role role) {
		//save role
		if(StringUtils.isEmpty(role.getId())) {
			role.setId(IdGen.uuid());
			role.setUseable(Constants.DEL_FLAG_NORMAL);
			role.setCreateBy(UserUtils.getUser().getId());
			role.setCreateDate(new Date());
			role.setUpdateBy(UserUtils.getUser().getId());
			role.setUpdateDate(new Date());
			roleDao.save(role);
		} else {
			role.setUpdateBy(UserUtils.getUser().getId());
			role.setUpdateDate(new Date());
			roleDao.update(role);
		}
		//save menu
		roleDao.batchUpdateRoleAndMenu(role.getId(), role.getMenuList());
		//save office
		roleDao.batchUpdateRoleAndOffice(role.getId(), role.getOfficeList());
		
		//clear cache
		systemRealm.clearAllCachedAuthorizationInfo();
		UserUtils.removeCache(UserUtils.CACHE_ROLE_LIST);
		
	}

	@Override
	@Transactional(readOnly = false)
	public void deleteRole(String id) {
		roleDao.deleteById(id);
		//clear cache
		systemRealm.clearAllCachedAuthorizationInfo();
		UserUtils.removeCache(UserUtils.CACHE_ROLE_LIST);
	}

	@Override
	@Transactional(readOnly = false)
	public Boolean outUserInRole(Role role, String userId) {
		return roleDao.deleteRoleAndUser(role.getId(), userId) == 1 ? true : false;
	}

	@Override
	@Transactional(readOnly = false)
	public User assignUserToRole(Role role, String userId) {
		roleDao.addRoleAndUser(role.getId(), userId);
		return userDao.getUser(userId);
	}

	@Override
	public Menu getMenu(String id) {
		return menuDao.get(id);
	}

	@Override
	public List<Menu> findAllMenu() {
		return menuDao.findAll();
	}

	@Override
	public void saveMenu(Menu menu) {
		User user = UserUtils.getUser();
		
		Menu parent = menuDao.get(menu.getParentId());
		String oldParentIds = menu.getParentIds(); // 获取修改前的parentIds，用于更新子节点的parentIds
		menu.setParentIds(parent.getParentIds()+parent.getId()+",");
		
		if(StringUtils.isEmpty(menu.getId())) {
			menu.setId(IdGen.uuid());
			menu.setCreateBy(user.getId());
			menu.setCreateDate(new Date());
			menu.setUpdateBy(user.getId());
			menu.setUpdateDate(new Date());
			
			menuDao.save(menu);
		} else {
			menu.setUpdateBy(user.getId());
			menu.setUpdateDate(new Date());
			
			menuDao.update(menu);
		}
		
		
		// 更新子节点 parentIds
		List<Menu> list = menuDao.findByParentIdsLike("%,"+menu.getId()+",%");
		for (Menu e : list){
			e.setParentIds(e.getParentIds().replace(oldParentIds, menu.getParentIds()));
		}
		menuDao.update(list);
		//clear cache
		systemRealm.clearAllCachedAuthorizationInfo();
		UserUtils.removeCache(UserUtils.CACHE_MENU_LIST);
	}

	@Override
	public void deleteMenu(String id) {
		menuDao.deleteById(id);
		//clear cache
		systemRealm.clearAllCachedAuthorizationInfo();
		UserUtils.removeCache(UserUtils.CACHE_MENU_LIST);
	}
	
	

}
